import React, { useRef, useEffect, useCallback, forwardRef, useImperativeHandle } from 'react';
import * as echarts from 'echarts';
import type { ECharts, EChartsOption } from 'echarts';
import CustomEmpty from '@/components/CustomEmpty';
import { debounce } from 'lodash';

export type ChartElementProps = {
  options?: EChartsOption;
  setOptionsNotMerge?: boolean;
  setOptionsLazyUpdate?: boolean;
  EChartsInitOpts?: any;
} & React.HTMLAttributes<HTMLDivElement>;

export type ChartElementRef = {
  resize: () => void;
  chartInstance: ECharts | null | undefined;
};

const ResizeChartElement = forwardRef<ChartElementRef, ChartElementProps>(
  ({ options, setOptionsNotMerge, setOptionsLazyUpdate, EChartsInitOpts, ...rest }, ref) => {
    const chartRef = useRef<HTMLDivElement>(null);
    const chartInstance = useRef<ECharts | null>();

    const debounceResize = debounce(() => {
      chartInstance.current?.resize({ width: 'auto', height: 'auto' });
    }, 50);

    const resize = useCallback(() => {
      if (chartInstance.current) {
        debounceResize();
      }
    }, [debounceResize]);

    useEffect(() => {
      if (!chartRef.current) return;
      if (!chartInstance.current) {
        chartInstance.current = echarts.init(chartRef.current, undefined, EChartsInitOpts);
      }
      if (!chartInstance.current) return;
      chartInstance.current.setOption(options || {}, setOptionsNotMerge, setOptionsLazyUpdate);
      const ele = chartRef.current;
      const observer = new ResizeObserver(() => {
        if (chartInstance.current) {
          resize();
        }
      });

      if (ele) {
        observer.observe(ele);
      }

      return () => {
        if (ele) {
          observer.unobserve(ele);
        }
        observer.disconnect();
      };
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [options]);

    useImperativeHandle(ref, () => ({
      resize,
      chartInstance: chartInstance.current,
    }));

    return options ? (
      <div ref={chartRef} style={{ height: '100%', width: '100%' }} {...rest} />
    ) : (
      <CustomEmpty />
    );
  },
);

export default ResizeChartElement;
